home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Wavy / Experiments / dynamicMap / staticMap.c copy < prev   
Encoding:
Text File  |  1993-06-17  |  8.7 KB  |  350 lines  |  [TEXT/KAHL]

  1. /*
  2.     Test mappings
  3. */
  4.  
  5. #include <QDOffscreen.h>
  6. #include <FixMath.h>
  7.  
  8. #define pictID    128
  9. #define    kFrameCount 16
  10.  
  11. void MapCoordinates(short width, short height, short x, short y, short *resultX, short *resultY)
  12. #define cycleSize    (8)
  13. {
  14. #define SineWave 1
  15. #define Mirror 0
  16.  
  17. #if Mirror
  18.     *resultX = width - x;
  19.     *resultY = y;
  20. #endif
  21.  
  22. #if SineWave
  23.     *resultX = x + (4*Frac2Fix(FracSin(y*205887/cycleSize))+32768)/65536;
  24.     *resultY = y;
  25. #endif
  26.  
  27.     while (*resultX < 0)
  28.         *resultX += width;
  29.     while (*resultY < 0)
  30.         *resultY += height;
  31.  
  32.     *resultX %= width;
  33.     *resultY %= height;
  34. }
  35.  
  36. /*
  37.     Generate the addresses for the mapping. 
  38. */
  39.  
  40. void
  41. GenerateMappingTable(long    *mappingTable, short width, short height, short rowBytes, short frameNumber)
  42. {
  43.     long    *offsetHere;
  44.     short    x, y;
  45.     
  46.     offsetHere = mappingTable;
  47.  
  48.     for (y = 0; y < height; ++y) {
  49.         for (x = 0; x < width; ++x)
  50.             {
  51.             short    destinationX, destinationY;
  52.  
  53.             MapCoordinates(width, height, x, y, &destinationX, &destinationY);
  54.             *offsetHere++ = (long)destinationY * rowBytes + destinationX;
  55.             }
  56.     }
  57. }
  58.  
  59. //
  60. // Blit the entire bitmap from source to dest
  61. //
  62.  
  63. void
  64. BlitThroughTable(char *sourceBase, char *destinationBase, short height, short width,
  65.             short rowBytes, long *mappingTable)
  66. {
  67.     short    x, y;
  68.     char    *sourceRow, *sourceByte;
  69.     long    *offsetHere;
  70.     
  71.     offsetHere = mappingTable;
  72.     
  73.     for (y = 0; y < height; ++y)
  74.         {
  75.         sourceRow = sourceBase;
  76.         for (x = 0; x < width; ++x)
  77.             *(destinationBase + *offsetHere++) = *sourceRow++;
  78.         sourceBase += rowBytes;
  79.         }
  80. }
  81.     
  82. //
  83. // Blit the entire bitmap from source to dest using a technique similar to what
  84. // we'd like to compile.
  85. //
  86. //    Use 5 destination registers so we can use 16-bit constant offsets in instructions
  87. //    of the form:
  88. //
  89. //    move.b    (sourceRow)+, tableValue(destReg[0..4])
  90. //    
  91. //    
  92. // Some useful instructions
  93. // 00000000: 207C 1234 5678        MOVEA.L    #$12345678,A0
  94. // 00000006: 227C 1234 5678        MOVEA.L    #$12345678,A1
  95. // 0000000C: 247C 1234 5678        MOVEA.L    #$12345678,A2
  96. // 00000012: 267C 1234 5678        MOVEA.L    #$12345678,A3
  97. // 00000018: 287C 1234 5678        MOVEA.L    #$12345678,A4
  98. // 0000001E: 2A7C 1234 5678        MOVEA.L    #$12345678,A5
  99. //
  100. // 00000006: 115D 1234             MOVE.B     (A5)+,$1234(A0)
  101. // 0000000A: 135D 1234             MOVE.B     (A5)+,$1234(A1)
  102. // 0000000E: 155D 1234            MOVE.B     (A5)+,$1234(A2)
  103. // 00000012: 175D 1234             MOVE.B     (A5)+,$1234(A3)
  104. // 00000016: 195D 1234            MOVE.B     (A5)+,$1234(A4)
  105.  
  106. // 00000038: 48E7 00FC            MOVEM.L    A0-A5,-(A7)
  107. // 0000003C: 4CDF 3F00            MOVEM.L    (A7)+,A0-A5
  108.  
  109. // 00000040: 4E75                RTS        
  110.  
  111. #define movea_to_a0        0x207c
  112. #define movea_to_a1        0x227c
  113. #define movea_to_a2        0x247c
  114. #define movea_to_a3        0x267c
  115. #define movea_to_a4        0x287c
  116. #define    movea_to_a5        0x2a7c
  117.  
  118. #define    move_b_a5plus_a0    0x115d
  119. #define    move_b_a5plus_a1    0x135d
  120. #define    move_b_a5plus_a2    0x155d
  121. #define    move_b_a5plus_a3    0x175d
  122. #define    move_b_a5plus_a4    0x195d
  123.  
  124. #define movem_push_a0_a5    0x48e700fcL
  125. #define movem_pop_a0_a5        0x4cdf3f00L
  126.  
  127. #define rts                0x4e75
  128.  
  129. void
  130. WriteSomeCode(char *sourceBase, char *destinationBase, short height, short width,
  131.                 short rowBytes, long *mappingTable, short *theCode)
  132. {
  133.     short    i, x, y;
  134.     char    *sourceRow, *sourceByte;
  135.     long    *offsetHere;
  136.     
  137.     char    *destRegisters[5];
  138.     long    registerRange;            // how much of a bitmap chunk each register sees
  139.     long    rangeOffset;            // where in the chunk each register points
  140.     long    targetBitMapSize;
  141.  
  142.     targetBitMapSize = (long) height * (long) rowBytes;
  143.     registerRange = (targetBitMapSize + 20) / 5;
  144.     rangeOffset = (registerRange / 2) & ~3;
  145.     
  146.     for (i = 0; i < 5; i++)
  147.         destRegisters[i] = destinationBase + registerRange * i + rangeOffset;
  148.     
  149.     offsetHere = mappingTable;
  150.  
  151.     // save the registers we trash
  152.     *(*(long **) &theCode)++ = movem_push_a0_a5;
  153.     
  154.     // load the 4 registers
  155.     *(*(short **) &theCode)++ = movea_to_a0;
  156.     *(*(char ***) &theCode)++ = destRegisters[0];
  157.     *(*(short **) &theCode)++ = movea_to_a1;
  158.     *(*(char ***) &theCode)++ = destRegisters[1];
  159.     *(*(short **) &theCode)++ = movea_to_a2;
  160.     *(*(char ***) &theCode)++ = destRegisters[2];
  161.     *(*(short **) &theCode)++ = movea_to_a3;
  162.     *(*(char ***) &theCode)++ = destRegisters[3];
  163.     *(*(short **) &theCode)++ = movea_to_a4;
  164.     *(*(char ***) &theCode)++ = destRegisters[4];
  165.         
  166.     for (y = 0; y < height; ++y)
  167.         {
  168.         sourceRow = sourceBase;
  169.  
  170.         // load the row register
  171.         *(*(short **) &theCode)++ = movea_to_a5;
  172.         *(*(char ***) &theCode)++ = sourceRow;
  173.  
  174.         for (x = 0; x < width; ++x) {
  175.             char    *targetByte;
  176.             long    registerOffset;
  177.             
  178.             targetByte = destinationBase + *offsetHere++;
  179.             
  180.             for (i = 0; i < 5; i++) {
  181.                 registerOffset = targetByte - destRegisters[i];
  182.                 if (registerOffset >= -32768 && registerOffset < 32768) {
  183.                     switch(i) {
  184.                         case 0:
  185.                             *(*(short **) &theCode)++ = move_b_a5plus_a0;
  186.                             *(*(short **) &theCode)++ = registerOffset;
  187.                             break;
  188.                         case 1:
  189.                             *(*(short **) &theCode)++ = move_b_a5plus_a1;
  190.                             *(*(short **) &theCode)++ = registerOffset;
  191.                             break;
  192.                         case 2:
  193.                             *(*(short **) &theCode)++ = move_b_a5plus_a2;
  194.                             *(*(short **) &theCode)++ = registerOffset;
  195.                             break;
  196.                         case 3:
  197.                             *(*(short **) &theCode)++ = move_b_a5plus_a3;
  198.                             *(*(short **) &theCode)++ = registerOffset;
  199.                             break;
  200.                         case 4:
  201.                             *(*(short **) &theCode)++ = move_b_a5plus_a4;
  202.                             *(*(short **) &theCode)++ = registerOffset;
  203.                             break;
  204.                         default:
  205.                             Debugger();
  206.                             break;
  207.                     }                
  208.                     break;
  209.                 }
  210.             }
  211.         }
  212.         sourceBase += rowBytes;
  213.     }
  214.     *(*(long **) &theCode)++ = movem_pop_a0_a5;
  215.     *(*(short **) &theCode)++ = rts;
  216. }
  217.     
  218. void
  219. CompileTable(char *sourceBase, char *destinationBase, short height, short width,
  220.         short rowBytes, long *mappingTable)
  221. {
  222.     short    x, y;        
  223.     
  224.     char    *sourceRow;
  225.     
  226.     for (y = 0; y < height; ++y)
  227.         {
  228.         sourceRow = sourceBase;
  229.         for (x = 0; x < width; ++x)
  230.             *(destinationBase + *mappingTable++) = *sourceRow++;
  231.         sourceBase += rowBytes;
  232.         }
  233. }
  234.  
  235. long Microseconds() = 0xA093;
  236.  
  237. main()
  238. {
  239.     WindowPtr        sourceWindow, destinationWindow;
  240.     Rect            sourceRect, destRect;
  241.     Rect            frame;
  242.     PicHandle        picture;
  243.     GWorldPtr        sourceGWorld, destinationGWorld;
  244.     PixMapHandle    sourcePix, destinationPix;
  245.     GWorldPtr        savedGWorld;
  246.     GDHandle        savedGDevice;
  247.     short            height, width, rowBytes;
  248.     short            x, y;
  249.     long            *buffer1, *offsetHere;
  250.     char            *sourceBase, *destinationBase;
  251.     long            *mappingTable;
  252.     short            *theCode;
  253.     long            startTime, endTime;
  254.     GrafPtr            windowManagerPort;
  255.  
  256.  
  257. #define PICTURE 1
  258.  
  259.     SetRect(&frame, 0, 0, 640, 480);
  260. #ifdef PICTURE    
  261.     picture = GetPicture(pictID);
  262.     frame = (**picture).picFrame;
  263. #endif
  264.  
  265.     width = frame.right - frame.left;
  266.     height = frame.bottom - frame.top;
  267.  
  268. #ifdef PICTURE
  269.     SetRect(&sourceRect, 50, 50, width + 50, height + 50);
  270.     destRect = sourceRect;
  271.     OffsetRect(&destRect, 0, 220);
  272.  
  273.     sourceWindow = NewCWindow(nil,&sourceRect,
  274.                             "\pSource", TRUE,
  275.                             documentProc, (WindowPtr)(-1), FALSE, 0);
  276.                             
  277.     destinationWindow = NewCWindow(nil,&destRect,
  278.                             "\pDestination", TRUE,
  279.                             documentProc, (WindowPtr)(-1), FALSE, 0);
  280. #else
  281.  
  282. //    destinationWindow = NewCWindow(nil,&frame,
  283. //                            "\pDestination", TRUE,
  284. //                            documentProc, (WindowPtr)(-1), FALSE, 0);
  285. #endif
  286.  
  287.     GetGWorld(&savedGWorld, &savedGDevice);
  288.     NewGWorld(&sourceGWorld,8,&frame,nil,nil,0);
  289.     NewGWorld(&destinationGWorld,8,&frame,nil,nil,0);
  290.     sourcePix = GetGWorldPixMap(sourceGWorld);
  291.     LockPixels(sourcePix);
  292.     SetGWorld(sourceGWorld, nil);
  293. #ifdef PICTURE
  294.     DrawPicture(picture,&sourceGWorld->portRect);
  295. #else
  296.     GetWMgrPort(&windowManagerPort);
  297.     CopyBits(&windowManagerPort->portBits, &((GrafPtr)sourceGWorld)->portBits,
  298.         &frame, &frame, srcCopy, nil);
  299. #endif
  300.     UnlockPixels(sourcePix);
  301.     SetGWorld(savedGWorld, savedGDevice);
  302.  
  303.     sourcePix = GetGWorldPixMap(sourceGWorld);
  304.     destinationPix = GetGWorldPixMap(destinationGWorld);
  305.     rowBytes = (**GetGWorldPixMap(sourceGWorld)).rowBytes & 0x7FFF;
  306.  
  307. #ifdef PICTURE
  308.     SetPort(sourceWindow);
  309.     LockPixels(sourcePix);
  310.     CopyBits((BitMap *)*sourcePix, &sourceWindow->portBits,
  311.          &sourceGWorld->portRect, &sourceWindow->portRect, srcCopy, nil);
  312.     UnlockPixels(sourcePix);
  313. #endif
  314.     
  315.     theCode = (short *)NewPtr(4L * width * height + 6 * height + 500L);
  316.     if (theCode == nil)
  317.         Debugger();
  318.         
  319.     mappingTable = (long *)NewPtr(sizeof(long) * (long)width * height);
  320.     if (mappingTable == nil)
  321.         Debugger();
  322.  
  323.     GenerateMappingTable(mappingTable, width, height, rowBytes, x);
  324.  
  325.     LockPixels(sourcePix);
  326.     LockPixels(destinationPix);
  327.  
  328.     sourceBase = (**sourcePix).baseAddr;
  329.     destinationBase = (**destinationPix).baseAddr;
  330.  
  331.     WriteSomeCode(sourceBase, destinationBase, height, width, rowBytes, mappingTable, theCode);
  332.  
  333.     startTime = Microseconds();
  334.     asm {
  335.         movea.l    theCode, a0
  336.         jsr        (a0)                // whee!
  337.     }
  338.     endTime = Microseconds();
  339.     
  340.     UnlockPixels(sourcePix);
  341.     UnlockPixels(destinationPix);
  342.  
  343.     SetPort(destinationWindow);
  344.     CopyBits((BitMap *)*destinationPix, &destinationWindow->portBits,
  345.          &destinationGWorld->portRect, &destinationWindow->portRect, srcCopy, nil);
  346.  
  347.     while (!Button());
  348.     while (Button());
  349. }
  350.